package com.wh.hotel.service.impl;

import cn.hutool.json.JSONUtil;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.wh.hotel.convert.HotelStructConvert;
import com.wh.hotel.dao.HotelRoomTypeGoodsDao;
import com.wh.hotel.enums.YesNoEnum;
import com.wh.hotel.model.HotelBookRule;
import com.wh.hotel.model.HotelRoomTypeGoods;
import com.wh.hotel.service.HotelRoomTypeGoodsService;
import com.wh.hotel.vo.HotelBookRuleVo;
import com.wh.hotel.vo.PayWayRuleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author wenhao
 */
@Slf4j
@Service
public class HotelRoomTypeGoodsServiceImpl implements HotelRoomTypeGoodsService {

    @Resource
    private HotelStructConvert hotelStructConvert;

    @Resource
    private HotelRoomTypeGoodsDao hotelRoomTypeGoodsDao;

    @Override
    public void addGoods(Long roomTypeId, HotelBookRule hotelBookRule) {
        List<HotelRoomTypeGoods> goodsList = initGoods(roomTypeId, hotelBookRule);
        for (List<HotelRoomTypeGoods> hotelRoomTypeGoodsList : Lists.partition(goodsList, 50)) {
            Preconditions.checkArgument(hotelRoomTypeGoodsDao.insertBatch(hotelRoomTypeGoodsList), "批量插入房型商品失败");
        }
    }

    @Override
    public void updateGoodsForRuleChange(Long roomTypeId, HotelBookRule newHotelBookRule) {
        // 查询老规则生成的商品
        Set<HotelRoomTypeGoods> oldGoodsSet = Sets.newHashSet(hotelRoomTypeGoodsDao.selectByRoomTypeId(roomTypeId));
        Set<HotelRoomTypeGoods> newGoodsSet = Sets.newHashSet(initGoods(roomTypeId, newHotelBookRule));
        Set<HotelRoomTypeGoods> needDeleteSet = Sets.difference(oldGoodsSet, newGoodsSet);
        Set<HotelRoomTypeGoods> needAddSet = Sets.difference(newGoodsSet, oldGoodsSet);
        hotelRoomTypeGoodsDao.deleteBatchByIdList(needDeleteSet.stream().map(HotelRoomTypeGoods::getId).collect(Collectors.toList()));
        hotelRoomTypeGoodsDao.insertBatch(Lists.newArrayList(needAddSet));
    }

    private List<HotelRoomTypeGoods> initGoods(Long roomTypeId, HotelBookRule hotelBookRule) {
        HotelBookRuleVo hotelBookRuleVo = hotelStructConvert.convertToHotelBookRuleVo(hotelBookRule);
        List<HotelRoomTypeGoods> goodsList = Lists.newArrayList();
        for (PayWayRuleVo payWayRuleVo : hotelBookRuleVo.getPayWayRuleVoList()) {
            for (Integer breakfast : hotelBookRuleVo.getBreakfastNumList()) {
                HotelRoomTypeGoods goods = createGoods(payWayRuleVo, breakfast);
                goods.setRoomTypeId(roomTypeId);
                goodsList.add(goods);
            }
        }
        return goodsList;
    }

    private HotelRoomTypeGoods createGoods(PayWayRuleVo payWayRuleVo, Integer breakfast) {
        HotelRoomTypeGoods goods = new HotelRoomTypeGoods();
        goods.setBreakfastNum(breakfast);
        goods.setPayWay(payWayRuleVo.getPayWay());
        goods.setCancelType(payWayRuleVo.getCancelType());
        goods.setGuaranteeType(payWayRuleVo.getGuaranteeType());
        goods.setGoodsStatus(YesNoEnum.NO.getCode());
        PayWayRuleVo copyRule = new PayWayRuleVo();
        copyRule.setFirstNightMinuteForStart(payWayRuleVo.getFirstNightMinuteForStart());
        copyRule.setFreeCancelMinuteForStart(payWayRuleVo.getFreeCancelMinuteForStart());
        goods.setCancelRule(JSONUtil.toJsonStr(copyRule));
        return goods;
    }
}
